#include "glrenderer.h"
#include <QMouseEvent>

GLRenderer::GLRenderer(QWidget *parent) : QGLWidget(parent)
{
    startTimer(40);
    setWindowTitle(tr("Model View"));
    m_lightAmbient[0] = m_lightAmbient[1] = m_lightAmbient[2] = 0.3f;
    m_lightSpecular[0] = m_lightSpecular[1] = m_lightSpecular[2] = 0.1f;
    m_lightAmbient[3] = m_lightSpecular[3] = 1.0f;
    m_lightPosition[0] = m_lightPosition[1] = m_lightPosition[2] = m_lightPosition[3] = 1.0f;
    m_rX = m_rY = 0.0f;
    m_Scale = 0.5f;
    m_Model = 0;
    m_preMouseX = m_preMouseY = 0.0f;
}

void GLRenderer::initializeGL()
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, 1.0, 0.1, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glLightfv(GL_LIGHT0, GL_SPECULAR, m_lightSpecular);
    glLightfv(GL_LIGHT0, GL_AMBIENT, m_lightAmbient);
    glLightfv(GL_LIGHT0, GL_POSITION, m_lightPosition);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glShadeModel(GL_SMOOTH);
}

void GLRenderer::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
    float r = (float) w / (float) h;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, r, 0.1, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void GLRenderer::setModel(model *m) {
    m_Model = m;
}

void GLRenderer::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    if(m_Model == 0) return;

    qglColor(Qt::white);
    glPushMatrix();
    glTranslatef(0.0f, 0.0f, -8.0f);
    glRotatef(m_rX, 1.0f, 0.0f, 0.0f);
    glRotatef(m_rY, 0.0f, 1.0f, 0.0f);
    glScalef(m_Scale, m_Scale, m_Scale);
    glLightfv(GL_LIGHT0, GL_POSITION, m_lightPosition);
    if(m_Model->vpf == 4) {
        glBegin(GL_QUADS);
    } else {
        glBegin(GL_TRIANGLES);
    }
    glTranslatef(0.0f, 0.0f, -m_Scale);
    int vi, ni;
    for(int i = 0; i < m_Model->vind_count; i++) {
        vi = m_Model->vinds[i]*3;
        ni = m_Model->ninds[i]*3;
         glNormal3f(m_Model->norms[ni],
                 m_Model->norms[ni + 1],
                 m_Model->norms[ni + 2]);
         glVertex3f(m_Model->verts[vi],
		 m_Model->verts[vi + 1],
		 m_Model->verts[vi + 2]);
    }
    glEnd();

    glPopMatrix();
}

void GLRenderer::timerEvent(QTimerEvent *)
{
    updateGL();
}

void GLRenderer::rotX(int rot)
{
    m_rX = 1.8 * rot;
}

void GLRenderer::rotY(int rot)
{
    m_rY = 1.8 * rot;
}

void GLRenderer::zoom(int scale)
{
    m_Scale = scale / 50.0f;
}

void GLRenderer::mouseMoveEvent(QMouseEvent * ev) {
    int dx = ev->x() - m_preMouseX;
    int dy = ev->y() - m_preMouseY;
    if(ev->buttons() & Qt::LeftButton) {
        m_rY -= dx;
        m_rX += dy;
    }
    m_preMouseX = ev->x();
    m_preMouseY = ev->y();
}

void GLRenderer::mousePressEvent(QMouseEvent * ev) {
    if(ev->buttons() & Qt::LeftButton) {
        m_preMouseX = ev->x();
        m_preMouseY = ev->y();
    }
}

void GLRenderer::setLightPos(float x, float y, float z) {
    m_lightPosition[0] = x;
    m_lightPosition[1] = y;
    m_lightPosition[2] = z;
}
